/**
Author: Maciej Oczko
Date: November 2011
*/

#ifndef TESTFUNCGENERIC_H
#define TESTFUNCGENERIC_H

#include "TestData.h"
#include "PoolMemoryManagerGeneric.h"
#include <vector>

template<typename T, unsigned elems>
void TestGeneric()
{
	PoolMemoryManagerGeneric<T> *pmm = new PoolMemoryManagerGeneric<T>(elems);
	clock_t start, stop;
	double diff;

	#ifndef OUT
	std::cout << "\n:: Generic Pool allocation (" << typeid(T).name() << " size: " << sizeof(T) << ", elements: " << elems << ") ::" << std::endl;
	#endif

	start = clock();
	PoolTestFunction<T>(pmm, elems);
	stop = clock();

	printTime(start, stop);

	#ifndef OUT
	std::cout << ":: Standard heap allocation (" << typeid(T).name() << " size: " << sizeof(T) << ", elements: " << elems << ") ::" << std::endl;
	#endif

	start = clock();
	HeapTestFunction<T>(elems);
	stop = clock();

	printTime(start, stop);
	delete pmm;
}


template<typename T>
void PoolTestFunction(PoolMemoryManagerGeneric<T>* pmm, unsigned random)
{
	log("Allocated " << pmm->GetCapacity() << " " << typeid(T).name() << " objects (object size: " << pmm->GetElementSize() << ").");
	log("Size of allocated memory: " << pmm->GetAllSize());

	std::vector<T *> vec;

	// Get some
	for(unsigned i = 0; i < random; ++i)
	{
		T * ptr = (T*) pmm->New();
		//log("[" << i << "] alloc address: " << ptr);
		vec.push_back(ptr);
	}

	log("Used count: " << pmm->GetUsedCount());
	log("Used size: " << pmm->GetUsedSize());
	log("Free count: " << pmm->GetFreeCount());
	log("Free size: " << pmm->GetFreeSize());

	log("Freeing ...");

	// Free some
	for(unsigned i = 0; i < vec.size(); ++i)
	{
		T * ptr = vec.back();
		vec.pop_back();
		//log("[" << i << "] free address: " << ptr);
		pmm->Delete(ptr);
	}

	log("Used count: " << pmm->GetUsedCount());
	log("Used size: " << pmm->GetUsedSize());
	log("Free count: " << pmm->GetFreeCount());
	log("Free size: " << pmm->GetFreeSize());
}

#endif